#include "stdafx.h"
#include "RegionScene.h"
#include "regionitem.h"


class RegionScenePrivate
{

public:
	RegionScenePrivate(RegionScene* parent)
		: undoStack(new QUndoStack(parent))
	{

	}
	QUndoStack* undoStack;
};
RegionScene::RegionScene(QObject *parent)
	: QGraphicsScene(parent)
	, d_ptr(new RegionScenePrivate(this))
{
	setItemIndexMethod(NoIndex);
	setBackgroundBrush(Qt::NoBrush);
}

RegionScene::~RegionScene()
{

}


QUndoStack* RegionScene::undoStack() const
{
	return d_func()->undoStack;
}

void RegionScene::addRegion(Region* item)
{
	Q_CHECK_PTR(item);
	QGraphicsScene::addItem(item);
	emit void regionChanged();
}


void RegionScene::removeRegion(Region* item)
{
	Q_CHECK_PTR(item);
	QGraphicsScene::removeItem(item);
	emit void regionChanged();
}

QList<Region*> RegionScene::selectedregionItems() const
{
	QList<QGraphicsItem*> selectedItems = QGraphicsScene::selectedItems();
	QList<Region*> selectedregionItems;
	foreach(QGraphicsItem *item, selectedItems)
	{
		Region* itemCased = qgraphicsitem_cast<Region*>(item);
		if (itemCased)
		{
			selectedregionItems.append(itemCased);
		}
	}
	return selectedregionItems;
}

Region* RegionScene::region(const QString& regionUUid)
{
	Region* region = 0;
	foreach(Region* item, regionItems())
	{
		if (item->regionUuid() == regionUUid)
		{
			region = item;
			break;
		}
	}
	return region;
}

QList<Region*> RegionScene::regionItems() const
{
	QList<Region*> selectedregionItems;
	foreach(QGraphicsItem *item, items())
	{
		Region* itemCased = qgraphicsitem_cast<Region*>(item);
		if (itemCased)
		{
			selectedregionItems.append(itemCased);
		}
	}
	return selectedregionItems;
}

QList<Region*> RegionScene::topLevelregionItems() const
{
	QList<Region*>  topLevelIems;
	foreach(Region* item, regionItems())
	{
		if (!item->parentItem())
		{
			topLevelIems.append(item);
		}
	}
	return topLevelIems;
}

RegionGroup* RegionScene::createRegionGroup(const QList<Region*>& items)
{
	// Build a list of the first item's ancestors
	QList<Region *> ancestors;
	int n = 0;
	if (!items.isEmpty()) {
		Region *parent = items.at(n++);
		while ((parent = parent->parentRegion()))
			ancestors.append(parent);
	}

	// Find the common ancestor for all items
	Region *commonAncestor = 0;
	if (!ancestors.isEmpty()) {
		while (n < items.size()) {
			int commonIndex = -1;
			Region *parent = items.at(n++);
			do {
				int index = ancestors.indexOf(parent, qMax(0, commonIndex));
				if (index != -1) {
					commonIndex = index;
					break;
				}
			} while ((parent = parent->parentRegion()));

			if (commonIndex == -1) {
				commonAncestor = 0;
				break;
			}

			commonAncestor = ancestors.at(commonIndex);
		}
	}

	// Create a new group at that level
	RegionGroup *group = new RegionGroup(commonAncestor);
	if (!commonAncestor)
	{
		QPolygonF boundingPolygon;
		foreach(Region *item, items)
		{
			QPolygonF itemBoundingPolygon = item->mapToScene(item->boundingRect());
			boundingPolygon << itemBoundingPolygon;
		}
		QRectF boundingRect = boundingPolygon.boundingRect();
		group->setRectangleSize(boundingRect.size());
		group->setPos(boundingRect.center());
		addRegion(group);
		group->setSelected(true);
	}
	foreach (Region *item, items)
	{
		item->setSelectable(false);
		group->addToGroup(item);
	}
	void regionChanged();
	return group;
}

void RegionScene::destroyRegionGroup(RegionGroup * group)
{
	foreach (Region *item, group->childregionItems())
	{		
		group->removeFromGroup(item);
		item->setSelectable(true);
	}
	removeRegion(group);
	emit regionChanged();
}

void RegionScene::sendRegionToBack(const QList<Region*>&) const
{
	foreach(Region* item, selectedregionItems())
	{
		QList<QGraphicsItem *> collidingItems = item->collidingItems();
		foreach(QGraphicsItem* collidingItem, collidingItems)
		{
			item->stackBefore(collidingItem);
		}
	}
}

void RegionScene::bringRegionToFront(const QList<Region*>&) const
{
	foreach(Region* item, selectedregionItems())
	{
		QList<QGraphicsItem *> collidingItems = item->collidingItems();
		foreach(QGraphicsItem* collidingItem, collidingItems)
		{
			collidingItem->stackBefore(item);
		}
	}
}

